
#define PURPLE_PLUGINS

#include <glib.h>
#include "plugin.h"
#include "version.h"
#include "util.h"
#include "debug.h"
#include "blist.h"
#include "account.h"
#include "prpl.h"
#include "xmlnode.h"
#include "request.h"

static PurplePlugin *this_plugin = NULL;

void
backup_import_buddies(const gchar *blist_filename)
{
	gchar *data;
	gsize size;
	xmlnode *purple_root;
	xmlnode *blist;
	xmlnode *group;
	xmlnode *setting;
	xmlnode *contact;
	xmlnode *buddy;
	gchar *alias;
	gchar *name;
	const gchar *account;
	const gchar *proto;
	PurpleGroup *pgroup;
	const gchar *setting_name;
	const gchar *setting_type;
	gchar *setting_value;
	PurpleBuddy *pbuddy;
	PurplePlugin *plugin;
	PurplePluginInfo *plugin_info;
	PurplePluginProtocolInfo *prpl_info; //extra_info
	PurpleAccount *paccount;
	PurpleConnection *pc;
	//PurpleContact *pcontact;
	
	// Load in the XML
	if (!g_file_get_contents(blist_filename, &data, &size, NULL))
	{
		purple_notify_error(this_plugin, "Error", "Could not open blist.xml file", NULL);
		purple_plugin_unload(this_plugin);
		return;
	}
	purple_root = xmlnode_from_str(data, size);
	
	blist = xmlnode_get_child(purple_root, "blist");
	
	// Loop through the groups
	group = xmlnode_get_child(blist, "group");
	for(; group; group = xmlnode_get_next_twin(group))
	{
		name = (gchar *)xmlnode_get_attrib(group, "name");
		
		// Add group if it doesn't exist
		pgroup = purple_find_group(name);
		if (!pgroup)
		{
			pgroup = purple_group_new(name);
			purple_blist_add_group(pgroup, NULL);
			
			// Grab the settigns for the group
			setting = xmlnode_get_child(group, "setting");
			for(; setting; setting = xmlnode_get_next_twin(setting))
			{
				setting_type = xmlnode_get_attrib(setting, "type");
				setting_name = xmlnode_get_attrib(setting, "name");
				setting_value = xmlnode_get_data(setting);
				
				if (g_str_equal(setting_type, "bool"))
				{
					purple_blist_node_set_bool((PurpleBlistNode *)pgroup, name, (setting_value[0]=='1'));
				} else if (g_str_equal(setting_type, "int"))
				{
					purple_blist_node_set_int((PurpleBlistNode *)pgroup, name, atoi(setting_value));
				} else if (g_str_equal(setting_type, "string"))
				{
					purple_blist_node_set_string((PurpleBlistNode *)pgroup, name, setting_value);
				}
				
				g_free(setting_value);
			}
		}
			
		// Loop through all the contacts inside the group
		contact = xmlnode_get_child(group, "contact");
		for(; contact; contact = xmlnode_get_next_twin(contact))
		{
			// Loop through all the buddies inside the contact
			buddy = xmlnode_get_child(contact, "buddy");
			for(; buddy; buddy = xmlnode_get_next_twin(buddy))
			{
				account = xmlnode_get_attrib(buddy, "account");
				proto = xmlnode_get_attrib(buddy, "proto");
				name = xmlnode_get_data(xmlnode_get_child(buddy, "name"));
				alias = xmlnode_get_data(xmlnode_get_child(buddy, "alias"));
				
				plugin = purple_find_prpl(proto);
				paccount = purple_accounts_find(account, proto);
				pbuddy = purple_find_buddy(paccount, name);
				
				if (!pbuddy)
				{
					pc = purple_account_get_connection(paccount);
				
					plugin_info = plugin->info;
					prpl_info = (PurplePluginProtocolInfo *) plugin_info->extra_info;
					
					pbuddy = purple_buddy_new(paccount, name, alias);
					if (prpl_info && prpl_info->add_buddy)
					{
						prpl_info->add_buddy(pc, pbuddy, pgroup);
					}
					else if (prpl_info && prpl_info->alias_buddy)
					{
						prpl_info->alias_buddy(pc, name, alias);
					}
					purple_blist_add_buddy(pbuddy, NULL, pgroup, NULL);
					
					
					// Grab the settigns for the buddy
					setting = xmlnode_get_child(buddy, "setting");
					for(; setting; setting = xmlnode_get_next_twin(setting))
					{
						setting_type = xmlnode_get_attrib(setting, "type");
						setting_name = xmlnode_get_attrib(setting, "name");
						setting_value = xmlnode_get_data(setting);
						
						if (g_str_equal(setting_type, "bool"))
						{
							purple_blist_node_set_bool((PurpleBlistNode *)pbuddy, name, (setting_value[0]=='1'));
						} else if (g_str_equal(setting_type, "int"))
						{
							purple_blist_node_set_int((PurpleBlistNode *)pbuddy, name, atoi(setting_value));
						} else if (g_str_equal(setting_type, "string"))
						{
							purple_blist_node_set_string((PurpleBlistNode *)pbuddy, name, setting_value);
						}
						
						g_free(setting_value);
					}
				}
				
				g_free(name);
				g_free(alias);
			}
		}
	}
	
	xmlnode_free(purple_root);
	g_free(data);
	
	purple_plugin_unload(this_plugin);
}

void
backup_restore_file_ok(gpointer userdata, const gchar *filename)
{
	backup_import_buddies(filename);
}

static void
init_plugin(PurplePlugin *plugin)
{
}

static gboolean
plugin_load(PurplePlugin *plugin)
{
	this_plugin = plugin;
	purple_request_file(plugin, "Restore from file...", "blist.xml", FALSE, (GCallback)backup_restore_file_ok, NULL, NULL, NULL, NULL, NULL);
	return TRUE;
}

static gboolean
plugin_unload(PurplePlugin *plugin)
{
	return TRUE;
}

static PurplePluginInfo info =
{
	PURPLE_PLUGIN_MAGIC,
	2,
	3,
	PURPLE_PLUGIN_STANDARD,
	NULL,
	0,
	NULL,
	PURPLE_PRIORITY_DEFAULT,
	"eionrobb-purple-restore",
	"Blist Restore", // Plugin name
	"0.1",

	"Restores your buddy list from a backup blist.xml", // Plugin Summary
	"", // Long desc
	"Eion Robb",
	"",
	plugin_load,
	plugin_unload,
	NULL, //plugin_destroy
	NULL,
	NULL,
	NULL,
	NULL
};

PURPLE_INIT_PLUGIN(purple_blist_restore, init_plugin, info)
